package websocket

import (
	"context"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/net/ghttp"
	"github.com/gogf/gf/v2/os/gctx"
	"github.com/gogf/gf/v2/os/glog"
	"github.com/gogf/gf/v2/util/gconv"
	"github.com/gorilla/websocket"
	"net/http"
	"server/internal/consts"
	"server/internal/service"
	"time"
)

var (
	hubManager = NewHub()
	ctx        = gctx.GetInitCtx()
)

func Logger() *glog.Logger {
	return g.Log("websocket")
}

func Start() {
	go hubManager.start()
	go hubManager.Ping()
}

// ServeWs handles websocket requests from the peer.
func ServeWs(r *ghttp.Request) {
	//解析用户信息
	claims, err := service.Jwt().ParseToken(r.Request.Context(), r.Request.URL.Query().Get("token"))
	if err != nil {
		Logger().Error(ctx, err.Error())
		return
	}
	if claims.UserId == 0 {
		Logger().Errorf(ctx, "user not login ")
		return
	}
	if !service.Jwt().ValidateAudience(claims, consts.JwtAudienceAdminWs) {
		Logger().Errorf(ctx, "user token audience use error")
		return
	}
	adminInfo, err := service.SystemUser().GetOneByID(ctx, claims.UserId)
	if err != nil {
		Logger().Errorf(ctx, "user info find error：%s", err.Error())
		return
	}

	upGrader := websocket.Upgrader{
		ReadBufferSize:  1024,
		WriteBufferSize: 1024,
		CheckOrigin: func(r *http.Request) bool {
			return true //允许所有来源
		},
	}
	conn, err := upGrader.Upgrade(r.Response.Writer, r.Request, nil)
	if err != nil {
		Logger().Error(ctx, err.Error())
		return
	}

	user := &UserData{
		Id:            int64(adminInfo.Id),
		Username:      adminInfo.Username,
		RememberToken: adminInfo.RememberToken,
		Name:          adminInfo.Name,
		Avatar:        adminInfo.Avatar,
		Phone:         adminInfo.Phone,
	}
	client := NewClient(r, conn, user)

	hubManager.register <- client //新用户注册

	go client.writePump() //监听需要给客户端发送的消息
	go client.readPump()  //监听客户端发送给服务端的消息
}

// getHeartbeatTimoutSecond 获取系统配置的默认心跳时间（秒）
func getHeartbeatTimoutSecond(ctx context.Context) time.Duration {
	//config, _ := g.Cfg().Get(ctx, "websocket.heartbeatTimeout")
	//if config.Int64() == 0 {
	//	return 60
	//}
	//return time.Second * time.Duration(config.Int64())
	//value, _ := service.SystemConfig().GetContentByCode(ctx, consts.ConfigCodeWsHeartbeatTimeout)
	value := 180
	data := gconv.Int64(value)
	if data <= 0 {
		data = 60 // 最低配置
	}
	return time.Second * time.Duration(data)
}

// getReadMessageMaxSize 获取客户端发送消息的最大容量
func getReadMessageMaxSize() int64 {
	return 2 * 1024 * 1024 //MB
}
